import 'package:dio/dio.dart' as dio;

import 'package:get/get.dart';
import 'package:mmkv/mmkv.dart';
import 'package:seedfour/app/constants.dart';
import 'package:seedfour/app/models/alloc_detail_entity.dart';
import 'package:seedfour/app/models/api_response/list_data_entity.dart';
import 'package:seedfour/app/models/case_all_entity.dart';
import 'package:seedfour/app/models/dictionary_entity.dart';
import 'package:seedfour/app/models/file_info_entity.dart';
import 'package:seedfour/app/models/invite_settles_entity.dart';
import 'package:seedfour/app/models/invite_user_entity.dart';
import 'package:seedfour/app/models/message_alert_entity.dart';
import 'package:seedfour/app/models/message_list_entity.dart';
import 'package:seedfour/app/models/notice_v2_entity.dart';
import 'package:seedfour/app/models/org_name_entity.dart';
import 'package:seedfour/app/models/sms_entity.dart';
import 'package:seedfour/app/models/transfer_user_entity.dart';
import 'package:seedfour/app/models/user_account_alloc_entity.dart';
import 'package:seedfour/app/models/user_account_entity.dart';
import 'package:seedfour/app/models/user_statistics_entity.dart';
import 'package:seedfour/app/remote/config.dart';
import 'package:seedfour/app/remote/request_client.dart';

import '../models/case_detail_entity.dart';
import '../models/case_list_entity.dart';
import '../models/case_order_list_entity.dart';
import '../models/file_list_entity.dart';
import '../models/file_search_list_entity.dart';
import '../models/fund_record_list_entity.dart';
import '../models/income_order_list_entity.dart';
import '../models/login_info_entity.dart';
import '../models/notice_v2_list_entity.dart';
import '../models/pay_order_list_entity.dart';
import '../models/payees_entity.dart';
import '../models/raw_data.dart';
import '../models/seal_detail_entity.dart';
import '../models/seal_list_entity.dart';
import '../models/team_user_entity.dart';
import '../models/user_info_entity.dart';
import '../remote/apis.dart';
import '../remote/exception.dart';
import '../routes/Event.dart';

class ApiService extends GetxService {
  final mmkv = MMKV.defaultMMKV();

  Future<LoginInfoEntity?> login(String mobile, String password, {onError}) =>
      requestClient
          .post<LoginInfoEntity>(
        APIS.login,
        data: {
          'mobile': mobile,
          'password': password,
          'did': kUUid,
          'site': 'app',
        },
        onError: onError,
      )
          .then((value) {
        if (value != null) {
          mmkv.encodeString(kKeyToken, value.token);
        }
        return Future.value(value);
      });

  Future<SmsEntity?> sendSms(String mobile) => requestClient.post<SmsEntity>(
        APIS.sendSms,
        data: {
          'mobile': mobile,
          'did': kUUid,
          'captcha': 'onlyForTesting',
        },
      );

  Future<LoginInfoEntity?> smsLogin(String mobile, String smsCode) =>
      requestClient.post<LoginInfoEntity>(
        APIS.smsLogin,
        data: {
          'mobile': mobile,
          'captcha': smsCode,
          'did': kUUid,
          'site': 'app',
        },
      ).then((value) {
        if (value != null) {
          mmkv.encodeString(kKeyToken, value.token);
        }
        return Future.value(value);
      });

  /// 微信登录功能
  Future<LoginInfoEntity?> wxLogin(String? code) =>
      requestClient.post<LoginInfoEntity>(
        APIS.wxLogin,
        data: {
          'code': code,
          'did': kUUid,
          'site': 'app',
          'source': 'sdk',
        },
      ).then((value) {
        if (value != null) {
          mmkv.encodeString(kKeyToken, value.token);
        }
        return Future.value(value);
      });

  /// 获取用户信息
  Future<UserInfoEntity?> getUserInfo({String? action}) =>
      requestClient.get<UserInfoEntity>(
        APIS.userInfo,
        queryParameters: {'role': 'me', 'action': action ?? ''},
      ).then((value) {
        if (value != null) {
          mmkv.encodeString(kKeyUser, value.toString());
          mmkv.encodeString(kKeyOrgId, value.targetSite?.owner);
          printInfo(info: '---------------------------------------- 发布事件');
          eventBus.fire(ChangeAccountEvent());
        }
        return Future.value(value);
      });

  /// 切换账户接口
  Future<RawData?> changeRole(String sysName, String orgId) =>
      requestClient.post<RawData>(
        APIS.changeRole,
        data: {
          'sysName': sysName,
          'orgId': orgId,
        },
      );

  /// 获取用户资产信息
  Future<UserAccountEntity?> getBalanceInfo(
    int page,
    int size,
    String action,
    String role,
    int? type,
    String? source,
  ) =>
      requestClient.post<UserAccountEntity>(
        APIS.balanceInfo,
        data: {
          'page': page,
          'size': size,
          'action': action,
          'role': role,
          'type': type,
          'source': source,
        },
      );

  Future<UserAccountAllocEntity?> getAllocInfo(
    int page,
    int pageSize,
    String role,
    int type,
  ) =>
      requestClient.post<UserAccountAllocEntity>(APIS.allocList, data: {
        'page': page,
        'pageSize': pageSize,
        'role': role,
        'type': type,
      });

  /// 获取专款详情信息
  Future<AllocDetailEntity?> getAllocDetail(String id) =>
      requestClient.post<AllocDetailEntity>(APIS.allocDetail, data: {'id': id});

  /// 获取专款流水信息
  Future<FundRecordListEntity?> getFundRecordList(
    int page,
    int pageSize,
    String role,
    int type,
  ) =>
      requestClient.post<FundRecordListEntity>(
        APIS.fundRecordList,
        data: {
          'page': page,
          'pageSize': pageSize,
          'role': role,
          'type': type.toString(),
        },
      );

  /// 获取消费平台免登录H5地址
  Future<RawData?> getBusinessUrl(String token, String businessType) =>
      requestClient.get<RawData>(
        '${RequestConfig.adminUrl}/app/auth/login',
        queryParameters: {
          'token': token,
          'businessType': businessType,
          'versionCode': 2,
        },
      );

  // 上传文件
  Future<FileInfoEntity?> uploadFile(String filePath,
          {bool Function(ApiException)? onError}) async =>
      requestClient.post<FileInfoEntity>(
        APIS.upload,
        data: dio.FormData.fromMap({
          'file': await dio.MultipartFile.fromFile(filePath),
        }),
        onError: onError,
      );

  // 下载文件
  Future<RawData?> download(int fileNo, String caseId, {String? type}) =>
      requestClient.post(APIS.download, data: {
        'fileNo': fileNo,
        'caseId': caseId,
        'type': type ?? 'delivery',
      });

  Future<RawData?> deleteFile(int fileNo, String caseId) =>
      requestClient.post(APIS.download, data: {
        'fileNo': fileNo,
        'caseId': caseId,
        'type': 'delete-contract-file',
      });

  // 获取支付密码公钥
  Future<String?> getPayKey({bool Function(ApiException)? onError}) =>
      requestClient.get<String>(APIS.getPayKey);

  // 修改密码
  Future<RawData?> changePassword(String newPwd,
      {String? oldPwd, String? token}) {
    final data = {
      'newPassword': newPwd,
    };
    if (oldPwd != null) {
      data['password'] = oldPwd;
    }
    if (token != null) {
      data['token'] = token;
    }

    return requestClient.post(APIS.changePassword, data: data);
  }

  // 发送短信验证码
  Future<SmsEntity?> sendSmsCode(String mobile) =>
      requestClient.post(APIS.sendSmsCode, data: {
        'did': 'CLICMS',
        'mobile': mobile,
      });

  Future<RawData?> setPayPwd(String password) =>
      requestClient.post(APIS.setPayPwd, data: {
        'action': 'update',
        'paypwd': password,
      });

  // 验证短信验证码
  Future<RawData?> verifySmsCode(String mobile, String code) =>
      requestClient.post(APIS.verifySmsCode, data: {
        'mobile': mobile,
        'captcha': code,
      });

  // 提现申请
  Future<RawData?> withdraw(
    String amount,
    String invoice,
    String password,
    bool Function(ApiException)? onError,
  ) =>
      requestClient.post<RawData>(
        APIS.withdraw,
        data: {
          'alipayMobile': '',
          'amount': amount,
          'bind': false,
          'invoice': invoice,
          'paymentPwd': password,
          'preview': false,
        },
        onError: onError,
      );

  // 获取转账用户列表
  Future<ListDataEntity<TransferUserEntity>?> getTransferUserList() =>
      requestClient.post(
        APIS.transferUsers,
        queryParameters: {
          'roleType': 'box',
          'userType': 'finduser',
        },
      );

  Future<ListDataEntity<InviteUserEntity>?> getInviteUserList() =>
      requestClient.get(APIS.inviteUsers);

  Future<MessageListEntity?> getMessageList(int page, int pageSize, int type) =>
      requestClient.post(APIS.messages, data: {
        'page': page,
        'pageSize': pageSize,
        'typeCat': type,
      });

  Future<MessageAlertEntity?> getMessageAlert(String role) =>
      requestClient.post(APIS.messageAlert, data: {
        'role': role,
      });

  Future<RawData?> messageRead(String role) =>
      requestClient.post(APIS.messageRead, data: {
        'role': role,
        'type': 1,
      });

  Future<InviteSettlesEntity?> getInviteSettleList(int page, int pageSize) =>
      requestClient.post(APIS.inviteSettles, data: {
        'action': 'queryflowlist',
        'page': page,
        'pageSize': pageSize,
      });

  Future<RawData?> transfer(String amount, String password, String targetUid,
          {String remark = ''}) =>
      requestClient.post(APIS.transfer, data: {
        'amount': amount,
        'targetUid': targetUid,
        'orderType': 6,
        'paymentPwd': password,
        'remark': remark,
      });

  Future<UserStatisticsEntity?> statistics(String year, String role) =>
      requestClient.post(APIS.statistics, data: {
        'action': 'dashboard',
        'role': role,
        'year': year,
      });

  Future<RawData?> approveStatus() => requestClient.get(APIS.approveStatus);

  // 获取我的团队成员列表
  Future<TeamUserEntity?> getTeamUsers() => requestClient.post(
        APIS.teamList,
      );

  // 删除团队成员
  Future<RawData?> deleteEdit(String? staffId) => requestClient.post(
        APIS.teamEdit,
        data: {
          'action': 'delete',
          'id': staffId,
        },
      );

  // 新增团队成员
  Future<RawData?> addEdit(String name, String mobile) => requestClient.post(
        APIS.teamEdit,
        data: {
          'code': '',
          'name': name,
          'mobile': mobile,
        },
      );

  // 获取案件列表
  Future<CaseListEntity?> listCase(
    int page,
    int pageSize,
    String role,
    String type, {
    String? caseName = '',
  }) {
    final data = {
      'page': page,
      'pageSize': pageSize,
      'role': role,
      'searchStage': type,
    };

    if (caseName != null && caseName.isNotEmpty) {
      data['caseName'] = caseName;
    }

    return requestClient.post(
      APIS.caseList,
      data: data,
    );
  }

  Future<ListDataEntity<OrgNameEntity>?> searchOrg(String name) =>
      requestClient.post(
        APIS.searchOrg,
        data: {
          'name': name,
        },
      );

  Future<RawData?> getCompanyInfo(String name) =>
      requestClient.post(APIS.companyInfo, data: {
        'name': name,
      });

  Future<CaseAllEntity?> listAllCase(String role,
          [String searchStage = 'all']) =>
      requestClient.post(
        APIS.caseList,
        data: {
          'role': role,
          'searchStage': searchStage,
        },
      );

  Future<CaseOrderListEntity?> getCaseOrderList(String action, String caseId,
          int startTime, int endTime, int orderType) =>
      requestClient.post(APIS.caseOrder, data: {
        'action': action,
        'caseId': caseId,
        'startTime': startTime,
        'endTime': endTime,
        'orderType': orderType,
      });

  Future<RawData?> caseOrderAction(
          String action, String caseId, String orderId, int orderAmount) =>
      requestClient.post(APIS.caseOrderAction, data: {
        'action': action,
        'caseId': caseId,
        'orderId': orderId,
        'orderAmount': orderAmount,
        'settleMethod': action == 'add' ? 'auto' : '0',
        'settleRatio': 0,
      });

  Future<ListDataEntity<DictionaryEntity>?> listDictionary(
          String dictionaryClass) =>
      requestClient.post(
        APIS.dictionary,
        data: {
          'dicClass': dictionaryClass,
        },
      );

  Future<CaseInfo?> createCase(
    String clientName,
    String clientCode, {
    String? oppositeName,
    String? oppositeCode,
    String? thirdName,
    String? thirdCode,
    String? otherInfo,
    String? suitType,
    String? lawsuitType,
    String? caseBusinessValue,
    String? caseClassValue,
    String? remarks,
    String? caseName,
  }) =>
      requestClient.post(
        APIS.createCase,
        data: {
          'action': 'createSubmit',
          'caseStatus': 'init',
          'clientName': clientName,
          'clientCode': clientCode,
          'oppositeName': oppositeName,
          'oppositeCode': oppositeCode,
          'thirdName': thirdName,
          'thirdCode': thirdCode,
          'otherInfo': otherInfo,
          'suitType': suitType,
          'lawsuitType': lawsuitType,
          'caseBusiness': caseBusinessValue,
          'caseClass': caseClassValue,
          'remarks': remarks,
          'caseName': caseName ?? '',
        },
      );

  Future<RawData?> editNotice(
    String role,
    String content,
    int shareType,
    String phoneNumber,
    String subjectAmount,
    String servicePrice, {
    String id = '',
    String title = '',
    int ownerContact = 0,
    int cooperRatio = 0,
    List<NoticeV2Attaches>? attaches,
  }) =>
      requestClient.post(
        ApisV2.noticeCreate,
        data: {
          'role': role,
          'content': content,
          'shareType': shareType,
          'phoneNumber': phoneNumber,
          'subjectAmount': subjectAmount,
          'servicePrice': servicePrice,
          if (id.isNotEmpty) 'id': id,
          if (title.isNotEmpty) 'title': title,
          'ownerContact': ownerContact,
          'cooperRatio': cooperRatio,
          'attaches': attaches,
        },
      );

  Future<CaseListEntity?> caseQuery(
    String clientName,
    String clientCode, {
    String? oppositeName,
    String? oppositeCode,
    String? thirdName,
    String? thirdCode,
    String? otherInfo,
    String? suitType,
    String? lawsuitType,
    String? caseBusinessValue,
    String? caseClassValue,
    String? remarks,
  }) =>
      requestClient.post(
        APIS.caseQuery,
        data: {
          'action': '',
          'caseStatus': 'init',
          'clientName': clientName,
          'clientCode': clientCode,
          'oppositeName': '',
          'oppositeCode': '',
          'thirdName': '',
          'thirdCode': '',
          'otherInfo': '',
          'suitType': '',
          'lawsuitType': '',
          'caseBusiness': '',
          'caseClass': '',
          'remarks': '',
        },
      );

  Future<CaseDetailEntity?> getCaseDetail(String caseId) =>
      requestClient.post(APIS.caseDetail, data: {
        'id': caseId,
      });

  Future<SealListEntity?> listSeal(
          int page, int pageSize, String role, int status, int type,
          {String? keyword}) =>
      requestClient.post(APIS.sealList, data: {
        'name': keyword ?? '',
        'page': page,
        'pageSize': pageSize,
        'role': role,
        'status': status,
        'type': type,
      });

  Future<RawData?> createSeal({
    required int sealPaperType,
    required int sealType,
    required int printNum,
    String? caseId = '',
    String? remark = '',
    bool Function(ApiException)? onError,
  }) =>
      requestClient.post(APIS.createSeal,
          data: {
            'action': 'createSubmit',
            'type': sealPaperType,
            'sealType': sealType,
            'printNum': printNum,
            'caseId': caseId,
            'remark': remark,
          },
          onError: onError);

  Future<RawData?> fileUpload(
          {required String action,
          required int fileIndex,
          required String filePath,
          String? caseId = '',
          bool Function(ApiException)? onError}) async =>
      requestClient.post<RawData>(
        APIS.fileUpload,
        data: dio.FormData.fromMap({
          'action': action,
          'fileno': fileIndex,
          'cid': caseId,
          'caseId': caseId,
          'file': await dio.MultipartFile.fromFile(filePath),
        }),
        onError: onError,
      );

  Future<SealDetailEntity?> getSealDetail(String id) =>
      requestClient.post(APIS.sealDetail, data: {
        'id': id,
      });

  Future<RawData?> cancelSeal(String id) =>
      requestClient.post(APIS.createSeal, data: {
        'action': 'cancelSubmit',
        'id': id,
      });

  Future<IncomeOrderListEntity?> getIncomeOrders(
          {required int page,
          required int pageSize,
          required String role,
          int? status,
          String? name}) =>
      requestClient.post(APIS.queryOrder, data: {
        'orderType': 4,
        'page': page,
        'pageSize': pageSize,
        'role': role,
        'status': status,
        'name': name ?? '',
      });
  Future<PayOrderListEntity?> getPayOrders(
          int page, int pageSize, String role, int status,
          {String? name}) =>
      requestClient.post(APIS.queryOrder, data: {
        'orderType': 6,
        'page': page,
        'pageSize': pageSize,
        'role': role,
        'status': status,
        'name': name ?? '',
      });

  Future<RawData?> deleteOrder(String orderId) =>
      requestClient.post(APIS.deleteOrder, data: {
        'orderId': orderId,
      });

  Future<String?> createPaidOrder({
    required String amount,
    required String invoice,
    required String mobile,
    required int orderType,
    required String paymentPwd,
    required String title,
    String? orderRemark,
  }) =>
      requestClient.post(APIS.createOrder, data: {
        'amount': amount,
        'invoice': invoice,
        'mobile': mobile,
        'orderRemark': orderRemark,
        'orderType': orderType,
        'paymentPwd': paymentPwd,
        'title': title,
      });

  Future<RawData?> createAssistantPaidOrder({
    required String action,
    required String amount,
    required String invoice,
    required String mobile,
    required int orderType,
    required String title,
    String? orderRemark,
  }) =>
      requestClient.post(APIS.assistantPayees, data: {
        'action': action,
        'amount': amount,
        'invoice': invoice,
        'mobile': mobile,
        'orderRemark': orderRemark,
        'orderType': orderType,
        'title': title,
      });

  Future<PayeesEntity?> getPayees(String mobile) =>
      requestClient.post(APIS.orderPayees, data: {
        'mobile': mobile,
      });

  Future<String?> createIncomeOrder({
    String? orderId,
    required String amount,
    required String invoice,
    required String mobile,
    required int settleRatio,
    required String title,
  }) =>
      requestClient.post(APIS.createOrder, data: {
        'orderId': orderId,
        'amount': amount,
        'invoice': invoice,
        'mobile': mobile,
        'settleRatio': settleRatio,
        'title': title,
      });

  Future<NoticeV2ListEntity?> getNoticeRecommendList(
          int page, int pageSize, String role, String action,
          {String? keyword = ''}) =>
      requestClient.post(ApisV2.recommendCaseList, data: {
        'page': page,
        'pageSize': pageSize,
        'action': action,
        'role': role,
        'name': keyword,
      });

  Future<NoticeV2ListEntity?> getNoticeList(
    int page,
    int pageSize,
    String role,
    String action, {
    String? keyword = '',
    int? status = 0,
  }) {
    final data = {
      'page': page,
      'pageSize': pageSize,
      'action': action,
      'role': role,
      'name': keyword,
    };

    if (status != null) {
      data['status'] = status;
    }

    return requestClient.post(ApisV2.notices, data: data);
  }

  Future<NoticeV2Entity?> getNoticeDetail(int id, String role) =>
      requestClient.post(ApisV2.noticeDetail, data: {
        'id': id,
        'role': role,
      });

  Future<String?> noticeAction(
    String action, {
    int? id,
    String? remark,
    String? caseId,
    String? caseName,
  }) =>
      requestClient.post(ApisV2.noticeAction, data: {
        'id': id,
        'action': action,
        'remark': remark ?? '',
        'caseId': caseId ?? '',
        'caseName': caseName ?? '',
      });

  Future<FileListEntity?> getFileList(int page, int pageSize, String role,
      {String? folderId}) {
    final data = {
      'page': page,
      'pageSize': pageSize,
      'role': role,
    };

    if (folderId != null) {
      data['dirId'] = folderId;
    }

    return requestClient.post(APIS.files, data: data);
  }

  Future<FileSearchListEntity?> searchFiles(int page, int pageSize, String role,
          {String? caseName = '',
          String? name = '',
          int? fileType,
          String? keyword}) =>
      requestClient.post(APIS.searchFiles, data: {
        'page': page,
        'pageSize': pageSize,
        'role': role,
        'caseName': caseName,
        'name': name,
        'deliveryType': fileType,
        'keyword': keyword,
      });

  // 专款提现
  Future<RawData?> allocOrderWithdraw(
      String id,
      String amount,
      String invoice,
      String password,
      bool Function(ApiException)? onError,
      ) =>
      requestClient.post<RawData>(
        APIS.allocAction,
        data: {
          'action': 'withdraw',
          'id': id,
          'amount': amount,
          'invoice': invoice,
          'paymentPwd': password,
        },
        onError: onError,
      );
  // 专款转账
  Future<RawData?> allocOrderTransfer(
      String id,
      String amount,
      String targetUid,
      String password,
      {String remark = ''}
      ) =>
      requestClient.post<RawData>(
        APIS.allocAction,
        data: {
          'action': 'transfer',
          'id': id,
          'amount': amount,
          'targetUid': targetUid,
          'remark': remark,
          'paymentPwd': password,
        }
      );
}
